package geektime.jdk.jmx;

import javax.management.MBeanServer;
import java.lang.management.*;
import java.util.Arrays;
import java.util.List;

/**
 * 通过MBean获取一些信息
 */
public class GetInfoByMBean {
    public static void main(String[] args) {
        System.out.println("--------------操作系统信息--------------");
        printOperationSystemInfo();
        System.out.println("--------------内存信息--------------");
        printMemoryInfo();
        System.out.println("--------------堆内管理者信息--------------");
        printMemoryManagerInfo();
        System.out.println("--------------内存池信息--------------");
        printMemoryPoolInfo();
        System.out.println("--------------类加载信息--------------");
        printClassLoadInfo();
        System.out.println("--------------线程信息--------------");
        printThreadInfo();
        System.out.println("--------------垃圾收集信息--------------");
        printGarbageCollectionInfo();
    }

    private static void printGarbageCollectionInfo() {
        List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMXBeans) {
            System.out.println("垃圾收集器名称：" + garbageCollectorMXBean.getName());
            System.out.println("垃圾收集器所在的内存池包含：" + Arrays.toString(garbageCollectorMXBean.getMemoryPoolNames()));
            System.out.println("垃圾收次数：" + garbageCollectorMXBean.getCollectionCount());
            System.out.println("垃圾收集耗时：" + garbageCollectorMXBean.getCollectionTime());
            System.out.println("###################################");
        }
    }

    private static void printThreadInfo() {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        System.out.println("所有的线程id：" + threadMXBean.getAllThreadIds());
        System.out.println("已经开始的线程数：" + threadMXBean.getTotalStartedThreadCount());
        System.out.println("线程数量：" + threadMXBean.getThreadCount());
        System.out.println("当前线程的CPU耗时（纳秒）：" + threadMXBean.getCurrentThreadCpuTime());
        System.out.println("守护线程数量：" + threadMXBean.getDaemonThreadCount());
        System.out.println("峰值线程数量：" + threadMXBean.getPeakThreadCount());
    }

    private static void printClassLoadInfo() {
        ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
        System.out.println("类加载数量：" + classLoadingMXBean.getLoadedClassCount());
        System.out.println("总的类加载数量：" + classLoadingMXBean.getTotalLoadedClassCount());
        System.out.println("未加载的类数量：" + classLoadingMXBean.getUnloadedClassCount());
    }

    private static void printMemoryPoolInfo() {
        List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
        for (MemoryPoolMXBean memoryPoolMXBean : memoryPoolMXBeans) {
            System.out.println("内存池类型：" + memoryPoolMXBean.getType());
            System.out.println("内存池名称：" + memoryPoolMXBean.getName());
            System.out.println("内存池已用：" + memoryPoolMXBean.getUsage());
            System.out.println("内存池最大用量：" + memoryPoolMXBean.getPeakUsage());
            System.out.println("内存池管理者：" + Arrays.toString(memoryPoolMXBean.getMemoryManagerNames()));
            System.out.println("内存池垃圾回收量：" + memoryPoolMXBean.getCollectionUsage());
//            System.out.println("内存池垃圾回收临界值：" + memoryPoolMXBean.getCollectionUsageThreshold());
//            System.out.println("内存池达到垃圾回收临界值次数：" + memoryPoolMXBean.getCollectionUsageThresholdCount());
//            System.out.println("内存池用量临界值：" + memoryPoolMXBean.getUsageThreshold());
//            System.out.println("内存池达到用量临界值的次数：" + memoryPoolMXBean.getUsageThresholdCount());
            System.out.println("###################################");
        }
    }

    private static void printMemoryManagerInfo() {
        List<MemoryManagerMXBean> memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans();
        for (MemoryManagerMXBean memoryManagerMXBean : memoryManagerMXBeans) {
            System.out.println("内存管理名称：" + memoryManagerMXBean.getName());
            System.out.println("内存管理池名称：" + Arrays.toString(memoryManagerMXBean.getMemoryPoolNames()));
            System.out.println("###################################");
        }
    }

    private static void printMemoryInfo() {
        MemoryMXBean memoryMBean = ManagementFactory.getMemoryMXBean();
        System.out.println("堆区内存情况：" + memoryMBean.getHeapMemoryUsage());
        System.out.println("非堆区内存情况：" + memoryMBean.getNonHeapMemoryUsage());
        System.out.println("等待被垃圾回收的对象数量：" + memoryMBean.getObjectPendingFinalizationCount());
    }

    private static void printOperationSystemInfo() {
        OperatingSystemMXBean osMBean = ManagementFactory.getOperatingSystemMXBean();
        System.out.println("操作系统名称：" + osMBean.getName());
        System.out.println("操作系统架构：" + osMBean.getArch());
        System.out.println("操作系统版本：" + osMBean.getVersion());
        System.out.println("操作系统处理器数量：" + osMBean.getAvailableProcessors());
        System.out.println("操作系统平均负载：" + osMBean.getSystemLoadAverage());
    }
}
